<?php

namespace app\user\home;

use app\index\home\Home;
use think\facade\Session;
use think\facade\Request;
use think\facade\Config;
use think\facade\Log;
use EasyWeChat\OfficialAccount\Application;
use app\user\model\CommonUser;
use thans\jwt\facade\JWTAuth;

/**
 * 微信授权控制器
 */
class Wechat extends Home
{
    /**
     * 微信应用实例
     */
    private $config;
    private $wxapp;

    public function __construct()
    {
        $this->config = Config::get('wechat');
        $this->wxapp = $this->createWechatApp();
    }

    /**
     * 微信授权页面
     */
    public function oauth()
    {
        $url = input('get.url/s','','remove_xss');
        if(!is_valid_url($url)){
            jerror('跳转链接错误');
        }

        $sessionKey = $this->config['middleware']['session_key'] ?? 'wechat_user';
        $wechatUser = Session::pull($sessionKey);

        try {
            if (!empty($wechatUser)) {
                $userInfo = CommonUser::addWechatUser($wechatUser);
                $token = JWTAuth::builder(['id' => $userInfo['id']]);
                $targetUrl = add_querystring_var($url, 'token', $token);

                return redirect($targetUrl);
            } else {
                Session::set('wechat_redirect_url', $url);
                $callbackUrl = Request::domain() . $this->config['oauth']['callback'];

                // 生成state参数防止CSRF攻击
                $state = $this->generateState();
                Session::set('wechat_oauth_state', $state);

                // 获取授权URL
                $oauth = $this->wxapp->getOAuth();
                $scopes = $this->config['oauth']['scopes'] ?? ['snsapi_userinfo'];
                $redirectUrl = $oauth->scopes($scopes)->withState($state)->redirect($callbackUrl);
                return redirect($redirectUrl);
            }
        } catch (\Exception $e) {
            Log::write('微信授权跳转失败: ' . $e->getMessage(), 'error');
            return json(['code' => 500, 'msg' => '授权失败，请重试']);
        }
    }

    /**
     * 微信授权回调处理
     */
    public function callback()
    {
        try {
            $code = Request::param('code');
            $state = Request::param('state');

            // 验证state参数
            if (!$this->validateState($state)) {
                throw new \Exception('无效的state参数');
            }

            if (!$code) {
                throw new \Exception('授权失败，未获取到code');
            }

            // 获取用户信息
            $oauth = $this->wxapp->getOAuth();
            $user = $oauth->userFromCode($code);

            // 转换用户数据格式
            $userArray = [
                'id' => $user->getId(),
                'nickname' => $user->getNickname(),
                'avatar' => $user->getAvatar(),
                'original' => $user->getRaw(),
            ];

            // 保存用户信息到数据库
            $userData = CommonUser::addWechatUser($userArray);
            if (!$userData) {
                throw new \Exception('用户信息保存失败');
            }

            // 保存用户信息到session
            $sessionKey = $this->config['middleware']['session_key'] ?? 'wechat_user';
            Session::set($sessionKey, $userData);

            // 清除state
            Session::delete('wechat_oauth_state');

            // 跳转到原页面或默认页面
            $redirectUrl = Session::pull('wechat_redirect_url');
            if (!$redirectUrl) {
                $redirectUrl = $this->config['oauth']['redirect_after_auth'] ?? '/';
            }

            $token = JWTAuth::builder(['id' => $userData['id']]);
            $redirectUrl = add_querystring_var($redirectUrl, 'token', $token);

            return redirect($redirectUrl);
        } catch (\Exception $e) {
            Log::write('微信授权回调失败: ' . $e->getMessage(), 'error');
            jerror('微信授权失败，请重试',10001);
        }
    }

    /**
     * 退出登录
     */
    public function logout()
    {
        $sessionKey = $this->config['middleware']['session_key'] ?? 'wechat_user';
        Session::delete($sessionKey);

        $redirectUrl = Request::param('redirect', '/');
        return redirect($redirectUrl);
    }

    /**
     * 获取当前用户信息
     */
    public function userinfo()
    {
        $sessionKey = $this->config['middleware']['session_key'] ?? 'wechat_user';
        $user = Session::get($sessionKey);
        if (!$user) {
            jerror('未授权',10001);
        }

        return jsuccess($user);
    }

    // JDK分享
    public function share()
    {
        //分享
        $url = input('get.url/s','','remove_xss');
        if(!is_valid_url($url)){
            jerror('跳转链接错误');
        }
        
        $url = $url ? $url : request()->url(true);

        $utils = $this->wxapp->getUtils();
        $config = $utils->buildJsSdkConfig(
                url: $url,
                jsApiList:[
                    'updateAppMessageShareData',
                    'updateTimelineShareData',
                    'hideMenuItems',
                    'startRecord',
                    'stopRecord',
                    'playVoice',
                    'onVoiceRecordEnd',
                    'uploadVoice',
                    'onVoicePlayEnd',
                    'downloadVoice',
                    'getLocation',
                    'chooseWXPay',
                    'scanQRCode',
                ],
                openTagList: [], 
                debug: false, 
        );

        jsuccess($config);
    }

    // 原生上传
    public function upload()
    {
        $mediaId = input('get.media/s','','remove_xss');
        if(!$mediaId) jerror('参数错误');

        jsuccess($mediaId);
    }

    /**
     * 创建微信应用实例
     */
    private function createWechatApp()
    {
        return new Application([
            'app_id' => $this->config['app_id'],
            'secret' => $this->config['secret'],
            'token' => $this->config['token'],
            'aes_key' => $this->config['aes_key'],

            'oauth' => [
                'scopes' => $this->config['oauth']['scopes'] ?? ['snsapi_userinfo'],
                'callback' => Request::domain() . $this->config['oauth']['callback'],
            ],

            'log' => [
                'level' => $this->config['log']['level'] ?? 'info',
                'file' => $this->config['log']['file'] ?? runtime_path() . 'log/wechat.log',
            ],
        ]);
    }

    /**
     * 生成state参数
     */
    private function generateState()
    {
        return md5(uniqid() . time() . mt_rand());
    }

    /**
     * 验证state参数
     */
    private function validateState($state)
    {
        $sessionState = Session::get('wechat_oauth_state');
        return $sessionState && $sessionState === $state;
    }
}
